import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/music_model.dart';
import '../services/music_api_service.dart';
import '../services/audio_service.dart';

// 音乐API服务提供者
final musicApiServiceProvider = Provider<MusicApiService>((ref) {
  return MusicApiService();
});

// 音频播放服务提供者
final audioServiceProvider = Provider<AudioPlayerService>((ref) {
  return AudioPlayerService();
});

// 搜索结果状态
class SearchState {
  final List<MusicModel> results;
  final bool isLoading;
  final String? error;
  final bool hasMore;
  final int currentPage;
  final bool isLoadingMore;

  const SearchState({
    this.results = const [],
    this.isLoading = false,
    this.error,
    this.hasMore = false,
    this.currentPage = 1,
    this.isLoadingMore = false,
  });

  SearchState copyWith({
    List<MusicModel>? results,
    bool? isLoading,
    String? error,
    bool? hasMore,
    int? currentPage,
    bool? isLoadingMore,
  }) {
    return SearchState(
      results: results ?? this.results,
      isLoading: isLoading ?? this.isLoading,
      error: error ?? this.error,
      hasMore: hasMore ?? this.hasMore,
      currentPage: currentPage ?? this.currentPage,
      isLoadingMore: isLoadingMore ?? this.isLoadingMore,
    );
  }
}

// 搜索状态管理
class SearchNotifier extends StateNotifier<SearchState> {
  final MusicApiService _apiService;
  String _lastKeyword = '';

  SearchNotifier(this._apiService) : super(const SearchState());

  Future<void> searchMusic(String keyword, {bool isNewSearch = true, String type = 'netease'}) async {
    if (keyword.trim().isEmpty) return;

    if (isNewSearch) {
      _lastKeyword = keyword;
      state = state.copyWith(isLoading: true, error: null, currentPage: 1);
    } else {
      if (state.isLoadingMore || !state.hasMore) return;
      state = state.copyWith(isLoadingMore: true);
    }

    try {
      final page = isNewSearch ? 1 : state.currentPage + 1;
      final response = await _apiService.searchMusic(keyword, page: page, type: type);
      
      final List<MusicModel> newResults = response['results'] ?? [];
      final bool hasMore = response['hasMore'] ?? false;
      final String? error = response['error'];

      if (error != null) {
        state = state.copyWith(
          isLoading: false,
          isLoadingMore: false,
          error: error,
        );
        return;
      }

      final List<MusicModel> allResults = isNewSearch 
          ? newResults 
          : [...state.results, ...newResults];

      state = state.copyWith(
        results: allResults,
        isLoading: false,
        isLoadingMore: false,
        hasMore: hasMore,
        currentPage: page,
        error: null,
      );
    } catch (e) {
      state = state.copyWith(
        isLoading: false,
        isLoadingMore: false,
        error: '搜索失败: $e',
      );
    }
  }

  Future<void> loadMore() async {
    if (_lastKeyword.isNotEmpty) {
      await searchMusic(_lastKeyword, isNewSearch: false);
    }
  }

  void clearResults() {
    state = const SearchState();
    _lastKeyword = '';
  }
}

final searchProvider = StateNotifierProvider<SearchNotifier, SearchState>((ref) {
  final apiService = ref.watch(musicApiServiceProvider);
  return SearchNotifier(apiService);
});

// 当前播放音乐状态
class PlayerState {
  final MusicModel? currentMusic;
  final bool isPlaying;
  final Duration position;
  final Duration duration;

  const PlayerState({
    this.currentMusic,
    this.isPlaying = false,
    this.position = Duration.zero,
    this.duration = Duration.zero,
  });

  PlayerState copyWith({
    MusicModel? currentMusic,
    bool? isPlaying,
    Duration? position,
    Duration? duration,
  }) {
    return PlayerState(
      currentMusic: currentMusic ?? this.currentMusic,
      isPlaying: isPlaying ?? this.isPlaying,
      position: position ?? this.position,
      duration: duration ?? this.duration,
    );
  }
}

class PlayerNotifier extends StateNotifier<PlayerState> {
  final AudioPlayerService _audioService;

  PlayerNotifier(this._audioService) : super(const PlayerState()) {
    _initializeListeners();
  }

  void _initializeListeners() {
    // 监听播放状态变化
    _audioService.playerStateStream.listen((playerState) {
      state = state.copyWith(isPlaying: playerState.playing);
    });

    // 监听播放位置变化
    _audioService.positionStream.listen((position) {
      state = state.copyWith(position: position);
    });

    // 监听时长变化
    _audioService.durationStream.listen((duration) {
      if (duration != null) {
        state = state.copyWith(duration: duration);
      }
    });
  }

  Future<void> playMusic(MusicModel music) async {
    try {
      state = state.copyWith(currentMusic: music);
      await _audioService.playMusic(music);
    } catch (e) {
      print('播放失败: $e');
    }
  }

  Future<void> togglePlayPause() async {
    if (state.isPlaying) {
      await _audioService.pause();
    } else {
      await _audioService.resume();
    }
  }

  Future<void> seek(Duration position) async {
    await _audioService.seek(position);
  }

  Future<void> stop() async {
    await _audioService.stop();
    state = const PlayerState();
  }

  void setCurrentMusic(MusicModel music) {
    state = state.copyWith(currentMusic: music);
  }

  void setPlaying(bool isPlaying) {
    state = state.copyWith(isPlaying: isPlaying);
  }

  void setPosition(Duration position) {
    state = state.copyWith(position: position);
  }

  void setDuration(Duration duration) {
    state = state.copyWith(duration: duration);
  }
}

final playerProvider = StateNotifierProvider<PlayerNotifier, PlayerState>((ref) {
  final audioService = ref.watch(audioServiceProvider);
  return PlayerNotifier(audioService);
});

// 收藏列表状态
final favoritesProvider = StateNotifierProvider<FavoritesNotifier, List<MusicModel>>((ref) {
  return FavoritesNotifier();
});

class FavoritesNotifier extends StateNotifier<List<MusicModel>> {
  FavoritesNotifier() : super([]);

  void addFavorite(MusicModel music) {
    if (!state.contains(music)) {
      state = [...state, music];
    }
  }

  void removeFavorite(MusicModel music) {
    state = state.where((item) => item != music).toList();
  }

  void clearAll() {
    state = [];
  }

  bool isFavorite(MusicModel music) {
    return state.contains(music);
  }
}